package com.woniu.service;

import com.woniu.adapter.*;
import com.woniu.inlet.web.vo.*;
import com.woniu.outlet.mysql.po.ProductBuyMySQL;
import com.woniu.outlet.mysql.po.ProductSellMySQL;
import com.woniu.outlet.redis.CodeOneRedisDao;
import com.woniu.outlet.redis.po.DailyCodeTOne;
import com.woniu.service.command.*;
import com.woniu.service.domain.FixedOrCurrentBuyDto;
import com.woniu.service.domain.FundOrGoldBuyDto;
import com.woniu.service.domain.TransactionDetailsDto;
import com.woniu.service.domain.UpdateBuyDto;
import com.woniu.utils.NumberRegexValidationUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

@Service
@Slf4j
@Transactional
public class OrderService implements
        FundOrGoldBuyCommandHandler, UpdateBuyStatusCommandHandler,
        FindUserOrderCommandHandler, FixedOrCurrentCommandHandler {

    @Autowired
    private ProductBuyAdapter buyAdapter;

    @Autowired
    private CodeOneRedisDao redisDao;

    @Autowired
    private PersonalIncomeAdapter personalIncomeAdapter;

    @Autowired
    private FixedCurrentIncomeAdapter fixedCurrentIncomeAdapter;

    @Autowired
    private ProductSellAdapter sellAdapter;


    /**
     * 基金或黄金的购买
     *
     * @param command
     */
    @Override
    public void productBuy(FundOrGoldBuyCommand command) {
        PayToOrderVo fo = command.getProductBuyFo();
        FundOrGoldBuyDto dto = FundOrGoldBuyDto.builder()
                .userId(Long.valueOf(fo.getUserId().toString()))
                .buyAmount(Integer.valueOf(fo.getMoney().toString()))
                .buyTime(fo.getPayTime())
                .codeId(fo.getCodeId())
                .payId(fo.getPayId())
                .productType(fo.getProductType())
                .build();
        buyAdapter.fundOrGoldBuy(dto);
    }

    /**
     * 修改待买入的订单信息为已买入
     * @param command
     */
    @Override
    public void updateBuyStatus(UpdateBuyStatusCommand command) {
        UpdateBuyDto dto = UpdateBuyDto.builder()
                .id(command.getOrderId())
                .buyCost(command.getBuyCost())
                .buyShare(command.getBuyShare())
                .build();
        log.debug("返回的手续费为{}，份额为{}", command.getBuyCost(), command.getBuyShare());
        buyAdapter.updateBuyStatus(dto);
    }

    /**
     * 查询用户所有的买入订单信息
     * @param findUserOrderCommand
     * @return
     */
    @Override
    public Object findUserOrder(FindUserOrderCommand findUserOrderCommand) {
        if(!NumberRegexValidationUtil.isPositiveInteger(findUserOrderCommand.getUserId()+"")){
            return "invalid";
        }
        List<ProductBuyMySQL> lists = buyAdapter.findUserOrder(findUserOrderCommand.getUserId());
        List<FindUserBuyOrderVo> vos = new ArrayList<>();
        if(lists.size()==0){
            return "0";
        }
        for (ProductBuyMySQL p : lists) {
            FindUserBuyOrderVo vo = new FindUserBuyOrderVo();
            BeanUtils.copyProperties(p, vo);
            if(p.getProductType().equals("fund") || p.getProductType().equals("gold")){
                DailyCodeTOne tOne =redisDao.findById(p.getCodeId()).orElseThrow(NullPointerException::new);
                vo.setName(tOne.getName());
            }
            if(p.getProductType().equals("fixed") || p.getProductType().equals("current")){
                String name = fixedCurrentIncomeAdapter.getName(p.getCodeId());
                vo.setName(name);
            }
            vos.add(vo);
        }
        return vos;
    }


    /**
     * 得到用户所有的卖出订单
     * @param userId
     */
    public Object findSellUserOrder(Long userId) {
        if(!NumberRegexValidationUtil.isPositiveInteger(userId+"")){
            return "invalid";
        }
        List<FindUserSellOrderVo> vos=new ArrayList<>();
        List<ProductSellMySQL> sells = sellAdapter.findSellUserOrder(userId);
        if(sells.size()==0){
            return "0";
        }
        for (ProductSellMySQL sell : sells) {
            FindUserSellOrderVo vo=new FindUserSellOrderVo();
            BeanUtils.copyProperties(sell,vo);
            vos.add(vo);
        }
        return vos;
    }



    /**
     * 定期或活期理财的购买
     *
     * @param command
     */
    @Override
    public void productBuy(FixedOrCurrentBuyCommand command) {
        PayToOrderVo fo = command.getProductBuyFo();
        Integer fixedDay = fo.getFixedDay();
        if(fo.getProductType().equals("current")){
            fixedDay=0;
        }
        FixedOrCurrentBuyDto dto = FixedOrCurrentBuyDto.builder()
                .userId(Long.valueOf(fo.getUserId().toString()))
                .buyAmount(Integer.valueOf(fo.getMoney().toString()))
                .buyTime(fo.getPayTime())
                .codeId(fo.getCodeId())
                .name(fo.getName())
                .fixedDay(fixedDay)
                .rateOfReturn(fo.getRateOfReturn())
                .payId(fo.getPayId())
                .productType(fo.getProductType())
                .build();
        buyAdapter.fixedOrCurrentBuy(dto);
    }

    /**
     * 根据产品类型查询持有产品详情
     * @param userId
     * @param productType
     * @return
     */
    public Object findAllUserHoldProductByType(Long userId, String productType) {
        if(!NumberRegexValidationUtil.isPositiveInteger(userId+"")){
            return "invalid";
        }
        if ("fund".equals(productType)) {
            UserFundAndGoldVo vo = personalIncomeAdapter.findUserFundProduct(userId);
            if (vo.getTotalAssets().toString().equals("0")) {
                return "0";
            }
            return vo;
        }
        if ("gold".equals(productType)) {
            UserFundAndGoldVo vo = personalIncomeAdapter.findUserGoldProduct(userId);
            if (vo.getTotalAssets().toString().equals("0")) {
                return "0";
            }
            return vo;
        }
        if ("fixed".equals(productType)) {
            UserFixedAndCurrentVo vo = fixedCurrentIncomeAdapter.findUserFixedProduct(userId);
            if (vo.getTotalAssets().toString().equals("0")) {
                return "0";
            }
            return vo;
        }
        if ("current".equals(productType)) {
            UserFixedAndCurrentVo vo = fixedCurrentIncomeAdapter.findUserCurrentProduct(userId);
            if (vo.getTotalAssets().toString().equals("0")) {
                return "0";
            }
            return vo;
        }
        return "invalid";
    }


}
